# -*- coding: utf-8 -*-
"""
@Time : 2024/12/22 5:02
@Author : 公众号——仰望天空的蜗牛
@Email : middlegod@sina.com
@File : weather.py
"""

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from base64 import b64encode, b64decode
from datetime import datetime
import requests
from urllib.parse import urlencode
import requests
from bs4 import BeautifulSoup
import pandas as pd


def get_crypte_param(city):
    """
    生成加密参数。
    用于请求接口，获取查看更多中的天气数据
    :param city: 加密参数的生成需要使用city
    :return: 返回加密参数
    """
    # AES加密密钥和IV
    key = '5ha5Z7cZ3WNbD3rA'.encode('utf-8')
    # 加密初始向量
    iv = 'AYk98XaiBwCi0Dst'.encode('utf-8')

    # 创建AES加密器
    cipher = AES.new(key, AES.MODE_CBC, iv)

    # 获取当前时间并格式化
    now = datetime.now()
    time_string = now.strftime("%Y%m%d%H%M%S")

    # 假设的城市名
    target_city = city

    # 要加密的数据
    data = f"{target_city}_{time_string}".encode()

    # 填充数据以符合块大小
    padded_data = pad(data, AES.block_size)

    # 加密数据
    encrypted_data = cipher.encrypt(padded_data)

    # 使用base64编码加密数据
    encrypted_string = b64encode(encrypted_data).decode('utf-8')

    return encrypted_string


def save_a_month_data(url):
    """
    保存一个月的天气历史数据，即一个页面中的数据
    :param url: 页面url 保存有某年某月的月数据所在的页面
    :return: 返回当月的二维天气数据列表
    """
    # 返回的当月的天气数据列表a_month
    a_month = []

    # 请求头
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"}
    # 请求url，响应r
    r = requests.get(url, headers=headers)
    soup = BeautifulSoup(r.text, 'html.parser')
    tianqi_zone = soup.find(class_='tian_three')
    try:
        tianqi_data = tianqi_zone.find(class_='thrui')
    except AttributeError:
        print(tianqi_zone)
        return a_month
    tianqi_data_a_month = tianqi_data.find_all('li')

    # 当月天气历史数据的处理
    for tianqi_data_a_day in tianqi_data_a_month:
        len_a_day_data = len(tianqi_data_a_day.text.split())
        if len_a_day_data == 7:
            a_day_data = tianqi_data_a_day.text.split()
            a_day_data.remove(a_day_data[1])
            a_month.append(a_day_data)
        else:
            a_month.append(tianqi_data_a_day.text.split())

    # 获取查看更多部分的天气数据
    url_split = [i for i in url.split('/') if i.strip("")]
    # print(url_split)
    # 城市名称拼音
    city_name = url_split[-2]
    # 年月份信息
    y_month = url_split[-1].strip(".html")
    # print(city_name, y_month)

    # 生成密参 crypte
    crypte = get_crypte_param(city_name)
    # print(crypte)

    params = {
        "crypte": crypte
    }
    api = f"http://lishi.tianqi.com/monthdata/{city_name}/{y_month}"
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
        "content-type": "application/json;", "referer": f"{url}"}
    r = requests.post(api, headers=headers, json=params)
    try:
        remainder_datas = r.json()
    except Exception as e:
        print(f"爬取{url}页面的查看更多数据时发生报错，报错信息：{e}")
        remainder_datas = []
    if remainder_datas:
        for remainder_data in remainder_datas:
            # 保存某天的天气数据temp_daily_data
            temp_daily_data = []

            # 日期
            date = remainder_data["date_str"]
            temp_daily_data.append(date)
            # 最高温度
            h_temp = str(remainder_data["htemp"]) + "℃"
            temp_daily_data.append(h_temp)
            # 最低温度
            l_temp = str(remainder_data["ltemp"]) + "℃"
            temp_daily_data.append(l_temp)
            # 天气情况
            weather = remainder_data["weather"]
            temp_daily_data.append(weather)
            # 风向
            wind = remainder_data["WD"]
            temp_daily_data.append(wind)
            # 风力
            wind_strong = remainder_data["WS"]
            temp_daily_data.append(wind_strong)

            # 加入月数据中
            a_month.append(temp_daily_data)

    return a_month


def decode_encrypted_data(data):
    # Base64 编码的字符串
    encoded_str = data

    # 解码 Base64 字符串
    iv_str = b64decode(encoded_str).decode('utf-8')  # 解码并转换为UTF-8字符串

    return iv_str  # 输出解码后的字符串


def main():
    # 城市 取https://www.tianqi.com/ 网站中存在的城市名拼音
    # eg.烟台
    city = "yantai"

    all_data = []

    # 遍历201101~202412之间的所有历史数据
    for year in range(2011, 2025):
        for month in range(1, 13):
            if month < 10:
                url = f"http://lishi.tianqi.com/{city}/{year}0{month}.html"
                # print(url)
            else:
                url = f"http://lishi.tianqi.com/{city}/{year}{month}.html"
                # print(url)
            a_month_data = save_a_month_data(url)
            all_data += a_month_data

    df = pd.DataFrame(all_data, columns=['日期', '最高气温', '最低气温', '天气', '风向', '风力'])
    # 保存所有的天气历史数据至本地excel文件中
    df.to_excel('a.xlsx', index=False)


if __name__ == '__main__':
    main()

    # a = ['QUVT', 'ZW5j', 'YXB1Rlg=', 'Z2V0RGF0ZQ==', 'QVlrOThYYWlCd0NpMERzdA==', 'UEl3eFk=',
    #      'XihbXiBdKyggK1teIF0rKSspK1teIF19', 'aW5mbw==', 'Y29uc3RydWN0b3I=', 'Vkp6c0c=', 'Y29tcGlsZQ==',
    #      'eFB4TkI=', 'Q05URWE=', 'bW9kZQ==', 'cFllRnA=', 'Y29uc29sZQ==', 'RlJtSmo=',
    #      'e30uY29uc3RydWN0b3IoInJldHVybiB0aGlzIikoICk=', 'ZW5jcnlwdA==', 'ZXJyb3I=', 'ZGVidWc=', 'd2Fybg==',
    #      'Y2pEdkQ=', 'bmhWQkY=', 'T3RQcmc=', 'cGFk', 'UmJzSXU=', 'dHJhY2U=', 'UGtjczc=', 'UFlnb0w=',
    #      'ZUhCUUM=', 'UWVVdWE=', 'WnpCRUQ=', 'Z2V0RnVsbFllYXI=', 'c3hVSHY=', 'ZnhDZVg=', 'ZXhjZXB0aW9u',
    #      'TGRRdWQ=', 'YXBwbHk=', 'cmV0dXJuIC8iICsgdGhpcyArICIv', 'd1hkVFo=', 'bFlkR0M=', 'bG9n', 'V1R6akQ=',
    #      'Ymhoelc=', 'S0NSd28=', 'cGFyc2U=', 'c3BsaXQ=', 'Z2V0TW9udGg=', 'a29xRVU=', 'dGVzdA==', 'dGFibGU=',
    #      'Mnw4fDd8MHwxfDl8NHw1fDZ8Mw==', 'cmV0dXJuIChmdW5jdGlvbigpIA==']
    # for i in a:
    #     iv_str = decode_encrypted_data(i)
    #     print(iv_str, len(iv_str), a.index(i))

    # month_data = save_a_month_data("http://lishi.tianqi.com/yantai/201101.html")
    # print(month_data)
